home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / hplip / hpssd.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-04-20  |  14.8 KB  |  421 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. __version__ = '12.0'
  5. __title__ = 'Services and Status System Tray dBus Child/Parent Process'
  6. __mod__ = 'hpssd'
  7. __doc__ = 'Provides persistent data and event services to HPLIP client applications. Required to be running for PC send fax, optional in all other cases.'
  8. import sys
  9. import struct
  10. import os
  11. import time
  12. import getopt
  13. import select
  14. import signal
  15. import tempfile
  16. from cPickle import loads, HIGHEST_PROTOCOL
  17. from base.g import *
  18. from base.codes import *
  19. from base import utils, device, status, models
  20.  
  21. try:
  22.     from dbus import lowlevel, SystemBus, SessionBus
  23.     import dbus.service as dbus
  24.     from dbus.mainloop.glib import DBusGMainLoop
  25.     from gobject import MainLoop, timeout_add, threads_init, io_add_watch, IO_IN
  26.     dbus_loaded = True
  27. except ImportError:
  28.     log.error('dbus failed to load (python-dbus ver. 0.80+ required). Exiting...')
  29.     dbus_loaded = False
  30.     sys.exit(1)
  31.  
  32. PIPE_BUF = 4096
  33. (dbus_loop, main_loop) = (None, None)
  34. system_bus = None
  35. session_bus = None
  36. (w1, w2, r3) = (None, None, None)
  37. devices = { }
  38.  
  39. class DeviceCache(object):
  40.     
  41.     def __init__(self, model = ''):
  42.         self.history = utils.RingBuffer(prop.history_size)
  43.         self.model = models.normalizeModelName(model)
  44.         self.cache = { }
  45.         self.faxes = { }
  46.         self.dq = { }
  47.         self.backoff_counter = 0
  48.         self.backoff_countdown = 0
  49.         self.polling = False
  50.  
  51.  
  52.  
  53. class StatusService(dbus.service.Object):
  54.     
  55.     def __init__(self, name, object_path):
  56.         dbus.service.Object.__init__(self, name, object_path)
  57.  
  58.     
  59.     def GetHistory(self, device_uri):
  60.         log.debug("GetHistory('%s')" % device_uri)
  61.         send_systray_blip()
  62.         
  63.         try:
  64.             devices[device_uri]
  65.         except KeyError:
  66.             return (device_uri, [])
  67.  
  68.         h = devices[device_uri].history.get()
  69.         log.debug('%d events in history:' % len(h))
  70.         [ x.debug() for x in h ]
  71.         return ([], [ x.as_tuple() for x in h ])
  72.  
  73.     GetHistory = dbus.service.method('com.hplip.StatusService', in_signature = 's', out_signature = 'sa(ssisisd)')(GetHistory)
  74.     
  75.     def GetStatus(self, device_uri):
  76.         log.debug("GetStatus('%s')" % device_uri)
  77.         send_systray_blip()
  78.         
  79.         try:
  80.             devices[device_uri]
  81.         except KeyError:
  82.             return (device_uri, { })
  83.  
  84.         t = { }
  85.         dq = devices[device_uri].dq
  86.         [ t.setdefault(x, str(dq[x])) for x in dq.keys() ]
  87.         log.debug(t)
  88.         return (device_uri, t)
  89.  
  90.     GetStatus = dbus.service.method('com.hplip.StatusService', in_signature = 's', out_signature = 'sa{ss}')(GetStatus)
  91.     
  92.     def SetCachedIntValue(self, device_uri, key, value):
  93.         log.debug("SetCachedIntValue('%s', '%s', %d)" % (device_uri, key, value))
  94.         if check_device(device_uri) == ERROR_SUCCESS:
  95.             devices[device_uri].cache[key] = value
  96.             return value
  97.         return -1
  98.  
  99.     SetCachedIntValue = dbus.service.method('com.hplip.StatusService', in_signature = 'ssi', out_signature = 'i')(SetCachedIntValue)
  100.     
  101.     def GetCachedIntValue(self, device_uri, key):
  102.         
  103.         try:
  104.             ret = devices[device_uri].cache[key]
  105.         except KeyError:
  106.             ret = -1
  107.  
  108.         log.debug("GetCachedIntValue('%s', '%s') --> %d" % (device_uri, key, ret))
  109.         return ret
  110.  
  111.     GetCachedIntValue = dbus.service.method('com.hplip.StatusService', in_signature = 'ss', out_signature = 'i')(GetCachedIntValue)
  112.     
  113.     def SetCachedStrValue(self, device_uri, key, value):
  114.         log.debug("SetCachedStrValue('%s', '%s', '%s')" % (device_uri, key, value))
  115.         if check_device(device_uri) == ERROR_SUCCESS:
  116.             devices[device_uri].cache[key] = value
  117.             return value
  118.         return ''
  119.  
  120.     SetCachedStrValue = dbus.service.method('com.hplip.StatusService', in_signature = 'sss', out_signature = 's')(SetCachedStrValue)
  121.     
  122.     def GetCachedStrValue(self, device_uri, key):
  123.         
  124.         try:
  125.             ret = devices[device_uri].cache[key]
  126.         except KeyError:
  127.             ret = ''
  128.  
  129.         log.debug("GetCachedStrValue('%s', '%s') --> %s" % (device_uri, key, ret))
  130.         return ret
  131.  
  132.     GetCachedStrValue = dbus.service.method('com.hplip.StatusService', in_signature = 'ss', out_signature = 's')(GetCachedStrValue)
  133.     
  134.     def CheckForWaitingFax(self, device_uri, username, job_id = 0):
  135.         log.debug("CheckForWaitingFax('%s', '%s', %d)" % (device_uri, username, job_id))
  136.         send_systray_blip()
  137.         r = (device_uri, '', 0, username, job_id, '', 0, '')
  138.         check_device(device_uri)
  139.         show_waiting_faxes(device_uri)
  140.         if job_id:
  141.             
  142.             try:
  143.                 devices[device_uri].faxes[(username, job_id)]
  144.             except KeyError:
  145.                 return r
  146.  
  147.             return self.check_for_waiting_fax_return(device_uri, username, job_id)
  148.         job_id
  149.         for u, j in devices[device_uri].faxes.keys():
  150.             if u == username:
  151.                 return self.check_for_waiting_fax_return(device_uri, u, j)
  152.         
  153.         return r
  154.  
  155.     CheckForWaitingFax = dbus.service.method('com.hplip.StatusService', in_signature = 'ssi', out_signature = 'ssisisds')(CheckForWaitingFax)
  156.     
  157.     def check_for_waiting_fax_return(self, d, u, j):
  158.         log.debug('Fax (username=%s, jobid=%d) removed from faxes and returned to caller.' % (u, j))
  159.         r = devices[d].faxes[(u, j)].as_tuple()
  160.         del devices[d].faxes[(u, j)]
  161.         show_waiting_faxes(d)
  162.         return r
  163.  
  164.     
  165.     def SendEvent(self, device_uri, printer_name, event_code, username, job_id, title):
  166.         event = device.Event(device_uri, printer_name, event_code, username, job_id, title)
  167.         handle_event(event)
  168.  
  169.     SendEvent = dbus.service.method('com.hplip.StatusService', in_signature = 'ssisis', out_signature = '')(SendEvent)
  170.  
  171.  
  172. def check_device(device_uri):
  173.     
  174.     try:
  175.         devices[device_uri]
  176.     except KeyError:
  177.         log.debug('New device: %s' % device_uri)
  178.         
  179.         try:
  180.             (back_end, is_hp, bus, model, serial, dev_file, host, port) = device.parseDeviceURI(device_uri)
  181.         except Error:
  182.             log.debug('Invalid device URI: %s' % device_uri)
  183.             return ERROR_INVALID_DEVICE_URI
  184.  
  185.         devices[device_uri] = DeviceCache(model)
  186.  
  187.     return ERROR_SUCCESS
  188.  
  189.  
  190. def create_history(event):
  191.     history = devices[event.device_uri].history.get()
  192.     if history and history[-1].event_code == event.event_code:
  193.         log.debug('Duplicate event. Replacing previous event.')
  194.         devices[event.device_uri].history.replace(event)
  195.         return True
  196.     devices[event.device_uri].history.append(event)
  197.     return False
  198.  
  199.  
  200. def handle_fax_event(event, pipe_name):
  201.     if event.event_code == EVENT_FAX_RENDER_COMPLETE and event.username == prop.username:
  202.         (fax_file_fd, fax_file_name) = tempfile.mkstemp(prefix = 'hpfax-')
  203.         pipe = os.open(pipe_name, os.O_RDONLY)
  204.         bytes_read = 0
  205.         while True:
  206.             data = os.read(pipe, PIPE_BUF)
  207.             if not data:
  208.                 break
  209.             
  210.             os.write(fax_file_fd, data)
  211.             bytes_read += len(data)
  212.         log.debug('Saved %d bytes to file %s' % (bytes_read, fax_file_name))
  213.         os.close(pipe)
  214.         os.close(fax_file_fd)
  215.         devices[event.device_uri].faxes[(event.username, event.job_id)] = device.FaxEvent(fax_file_name, event)
  216.         show_waiting_faxes(event.device_uri)
  217.         
  218.         try:
  219.             os.waitpid(-1, os.WNOHANG)
  220.         except OSError:
  221.             pass
  222.  
  223.         (ok, lock_file) = utils.lock_app('hp-sendfax-%s' % event.printer_name, True)
  224.         if ok:
  225.             utils.unlock(lock_file)
  226.             path = utils.which('hp-sendfax')
  227.             if path:
  228.                 path = os.path.join(path, 'hp-sendfax')
  229.             else:
  230.                 log.error('Unable to find hp-sendfax on PATH.')
  231.                 return None
  232.             path.debug('Running hp-sendfax: %s --printer=%s' % (path, event.printer_name))
  233.             os.spawnlp(os.P_NOWAIT, path, 'hp-sendfax', '--printer=%s' % event.printer_name)
  234.         else:
  235.             log.debug('hp-sendfax is running. Waiting for CheckForWaitingFax() call.')
  236.     else:
  237.         log.warn('Not handled!')
  238.  
  239.  
  240. def show_waiting_faxes(d):
  241.     f = devices[d].faxes
  242.     if not len(f):
  243.         log.debug('No faxes waiting for %s' % d)
  244.     elif len(f) == 1:
  245.         log.debug('1 fax waiting for %s:' % d)
  246.     else:
  247.         log.debug('%d faxes waiting for %s:' % (len(f), d))
  248.     [ f[x].debug() for x in f ]
  249.  
  250.  
  251. def handle_hpdio_event(event, bytes_written):
  252.     log.debug('Reading %d bytes from hpdio pipe...' % bytes_written)
  253.     (total_read, data) = (0, '')
  254.     while True:
  255.         (r, w, e) = select.select([
  256.             r3], [], [
  257.             r3], 0)
  258.         if not r:
  259.             break
  260.         
  261.         x = os.read(r3, PIPE_BUF)
  262.         if not x:
  263.             break
  264.         
  265.         data = ''.join([
  266.             data,
  267.             x])
  268.         total_read += len(x)
  269.         if total_read == bytes_written:
  270.             break
  271.             continue
  272.     log.debug('Read %d bytes' % total_read)
  273.     if total_read == bytes_written:
  274.         dq = loads(data)
  275.         if check_device(event.device_uri) == ERROR_SUCCESS:
  276.             devices[event.device_uri].dq = dq.copy()
  277.             handle_event(device.Event(event.device_uri, '', dq.get('status-code', STATUS_PRINTER_IDLE), prop.username, 0, ''))
  278.             send_toolbox_event(event, EVENT_DEVICE_UPDATE_REPLY)
  279.         
  280.     
  281.  
  282.  
  283. def handle_event(event, more_args = None):
  284.     log.debug('Handling event...')
  285.     if more_args is None:
  286.         more_args = []
  287.     
  288.     event.debug()
  289.     if event.device_uri and check_device(event.device_uri) != ERROR_SUCCESS:
  290.         return None
  291.     if event.event_code > EVENT_MAX_EVENT:
  292.         event.event_code = status.MapPJLErrorCode(event.event_code)
  293.     
  294.     if event.event_code < EVENT_MIN_USER_EVENT:
  295.         pass
  296.     elif event.event_code <= event.event_code:
  297.         pass
  298.     elif event.event_code <= EVENT_MAX_USER_EVENT:
  299.         if event.device_uri:
  300.             dup_event = create_history(event)
  301.             if event.event_code in (EVENT_DEVICE_STOP_POLLING, EVENT_START_MAINT_JOB, EVENT_START_COPY_JOB, EVENT_START_FAX_JOB, EVENT_START_PRINT_JOB):
  302.                 pass
  303.             elif event.event_code in (EVENT_DEVICE_START_POLLING, EVENT_END_MAINT_JOB, EVENT_END_COPY_JOB, EVENT_END_FAX_JOB, EVENT_END_PRINT_JOB, EVENT_PRINT_FAILED_MISSING_PLUGIN, EVENT_SCANNER_FAIL, EVENT_END_SCAN_JOB, EVENT_SCAN_FAILED_MISSING_PLUGIN, EVENT_FAX_JOB_FAIL, EVENT_FAX_JOB_CANCELED, EVENT_FAX_FAILED_MISSING_PLUGIN, EVENT_COPY_JOB_FAIL, EVENT_COPY_JOB_CANCELED):
  304.                 pass
  305.             
  306.         
  307.         if not dup_event:
  308.             send_event_to_systray_ui(event)
  309.         
  310.         send_toolbox_event(event, EVENT_HISTORY_UPDATE)
  311.     elif event.event_code <= event.event_code:
  312.         pass
  313.     elif event.event_code <= EVENT_FAX_MAX and more_args:
  314.         log.debug('Fax event')
  315.         pipe_name = str(more_args[0])
  316.         handle_fax_event(event, pipe_name)
  317.     elif event.event_code == EVENT_USER_CONFIGURATION_CHANGED:
  318.         send_event_to_systray_ui(event)
  319.     elif event.event_code == EVENT_SYS_CONFIGURATION_CHANGED:
  320.         send_event_to_systray_ui(event)
  321.     elif event.event_code in (EVENT_DEVICE_UPDATE_REQUESTED,):
  322.         send_event_to_hpdio(event)
  323.     elif event.event_code in (EVENT_DEVICE_UPDATE_ACTIVE, EVENT_DEVICE_UPDATE_INACTIVE):
  324.         send_event_to_systray_ui(event)
  325.     elif event.event_code == EVENT_DEVICE_UPDATE_REPLY:
  326.         bytes_written = int(more_args[1])
  327.         handle_hpdio_event(event, bytes_written)
  328.     elif event.event_code == EVENT_SYSTEMTRAY_EXIT:
  329.         send_event_to_hpdio(event)
  330.         send_toolbox_event(event)
  331.         send_event_to_systray_ui(event)
  332.         log.debug('Exiting')
  333.         main_loop.quit()
  334.     elif event.event_code in (EVENT_DEVICE_START_POLLING, EVENT_DEVICE_STOP_POLLING):
  335.         pass
  336.     else:
  337.         log.error('Unhandled event: %d' % event.event_code)
  338.  
  339.  
  340. def send_systray_blip():
  341.     send_event_to_systray_ui(device.Event('', '', EVENT_DEVICE_UPDATE_BLIP))
  342.  
  343.  
  344. def send_event_to_systray_ui(event, event_code = None):
  345.     e = event.copy()
  346.     if event_code is not None:
  347.         e.event_code = event_code
  348.     
  349.     e.send_via_pipe(w1, 'systemtray')
  350.  
  351.  
  352. def send_event_to_hpdio(event):
  353.     event.send_via_pipe(w2, 'hpdio')
  354.  
  355.  
  356. def send_toolbox_event(event, event_code = None):
  357.     e = event.copy()
  358.     if event_code is not None:
  359.         e.event_code = event_code
  360.     
  361.     e.send_via_dbus(session_bus, 'com.hplip.Toolbox')
  362.  
  363.  
  364. def handle_signal(typ, *args, **kwds):
  365.     if kwds['interface'] == 'com.hplip.StatusService' and kwds['member'] == 'Event':
  366.         event = device.Event(*args[:6])
  367.         return handle_event(event, args[6:])
  368.  
  369.  
  370. def handle_system_signal(*args, **kwds):
  371.     return handle_signal('system', *args, **kwds)
  372.  
  373.  
  374. def handle_session_signal(*args, **kwds):
  375.     return handle_signal('session', *args, **kwds)
  376.  
  377.  
  378. def run(write_pipe1 = None, write_pipe2 = None, read_pipe3 = None):
  379.     global w1, w2, r3, dbus_loop, main_loop, system_bus, session_bus
  380.     log.set_module('hp-systray(hpssd)')
  381.     log.debug('PID=%d' % os.getpid())
  382.     w1 = write_pipe1
  383.     w2 = write_pipe2
  384.     r3 = read_pipe3
  385.     dbus_loop = DBusGMainLoop(set_as_default = True)
  386.     main_loop = MainLoop()
  387.     
  388.     try:
  389.         system_bus = SystemBus(mainloop = dbus_loop)
  390.     except dbus.exceptions.DBusException:
  391.         e = None
  392.         log.error('Unable to connect to dbus system bus. Exiting.')
  393.         sys.exit(1)
  394.  
  395.     
  396.     try:
  397.         session_bus = dbus.SessionBus()
  398.     except dbus.exceptions.DBusException:
  399.         e = None
  400.         if os.getuid() != 0:
  401.             log.error('Unable to connect to dbus session bus. Exiting.')
  402.             sys.exit(1)
  403.         else:
  404.             log.error('Unable to connect to dbus session bus (running as root?)')
  405.             sys.exit(1)
  406.     except:
  407.         os.getuid() != 0
  408.  
  409.     system_bus.add_signal_receiver(handle_system_signal, sender_keyword = 'sender', destination_keyword = 'dest', interface_keyword = 'interface', member_keyword = 'member', path_keyword = 'path')
  410.     session_bus.add_signal_receiver(handle_session_signal, sender_keyword = 'sender', destination_keyword = 'dest', interface_keyword = 'interface', member_keyword = 'member', path_keyword = 'path')
  411.     session_name = dbus.service.BusName('com.hplip.StatusService', session_bus)
  412.     status_service = StatusService(session_name, '/com/hplip/StatusService')
  413.     log.debug('Entering main dbus loop...')
  414.     
  415.     try:
  416.         main_loop.run()
  417.     except KeyboardInterrupt:
  418.         log.debug('Ctrl-C: Exiting...')
  419.  
  420.  
  421.